package com.gscitysfy.cus.drain.modules.command.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.gscitysfy.cus.drain.config.BusinessException;
import com.gscitysfy.cus.drain.modules.command.dto.ResourceDispatchDto;
import com.gscitysfy.cus.drain.modules.command.dto.SendMessage;
import com.gscitysfy.cus.drain.modules.command.dto.SendMessageRequest;
import com.gscitysfy.cus.drain.modules.command.entity.*;
import com.gscitysfy.cus.drain.modules.command.mapper.*;
import com.gscitysfy.cus.drain.modules.command.service.*;
import com.gscitysfy.cus.drain.modules.command.vo.ResourceDispatchQuery;
import com.gscitysfy.cus.drain.modules.resource.dto.DrainBaseMnWarehouseDto;
import com.gscitysfy.cus.drain.modules.resource.dto.ResourceCarDto;
import com.gscitysfy.cus.drain.modules.resource.dto.ResourceTeamDto;
import com.gscitysfy.cus.drain.modules.resource.service.IDrainBaseMnWarehouseService;
import com.gscitysfy.cus.drain.modules.resource.service.IResourceCarService;
import com.gscitysfy.cus.drain.modules.resource.service.IResourceTeamService;
import com.gscitysfy.cus.drain.task.alarmToSitulationTask;
import com.gscitysfy.cus.drain.utils.HttpUtils;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @Author jiang_wen
 * @Date 2022/10/21 16:39
 * @Description TODO
 */
@Service
public class ResourceDispatchServiceImpl implements IResourceDispatchService {
    @Autowired
    private  IInstructCarService iInstructCarService;
    @Autowired
    private  InstructWarehouseService instructWarehouseService;
    @Autowired
    private  IInstructTeamService iInstructTeamService;
    @Autowired
    private  IResourceCarService iResourceCarService;
    @Autowired
    private  IDrainBaseMnWarehouseService iResourceWarehouseService;
    @Autowired
    private  IResourceTeamService iResourceTeamService;
    @Autowired
    private  DrainCommandDispatchSchemeCarMapper drainCommandDispatchSchemeCarMapper;
    @Autowired
    private  DrainCommandDispatchSchemeTeamMapper drainCommandDispatchSchemeTeamMapper;

    @Autowired
    private  DangerSituationManageMapper dangerSituationManageMapper;
    @Autowired
    private  InstructTeamMapper instructTeamMapper;
    @Autowired
    private  InstructCarMapper instructCarMapper;

    private static final Logger logger = LoggerFactory.getLogger(ResourceDispatchServiceImpl.class);
    @Value("${xcydd.host}")
    String host;

    @Value("${xcydd.app_secret}")
    String appSecret;
    @Override
    public ResourceDispatchDto fetchSchemeList(ResourceDispatchQuery query) {
        ResourceDispatchDto resourceDispatchDto = new ResourceDispatchDto();

        //需要获取调度方案的待命的车辆和队伍List，再取二者的交集即可
        //选择调度方案，根据等级和调度方案获取车辆和队伍
        List<DrainCommandDispatchSchemeCar> selectSchemeCarList = new ArrayList<DrainCommandDispatchSchemeCar>();
        List<DrainCommandDispatchSchemeTeam> selectSchemeTeamList = new ArrayList<DrainCommandDispatchSchemeTeam>();

        //根据险情id，获取预案的等级
        DangerSituationManage dangerSituation = dangerSituationManageMapper.selectById(query.getDangerSituationId());
        if(dangerSituation!=null&&StringUtils.isNotEmpty(dangerSituation.getReservePlanLevel())){
            DrainCommandDispatchSchemeCar drainCommandDispatchSchemeCar = new DrainCommandDispatchSchemeCar();
            drainCommandDispatchSchemeCar.setLevel(dangerSituation.getReservePlanLevel());
            drainCommandDispatchSchemeCar.setSchemeId(query.getSchemeId());
            List<DrainCommandDispatchSchemeCar> schemeCarList =drainCommandDispatchSchemeCarMapper.getPageList(drainCommandDispatchSchemeCar);
            if(CollectionUtils.isNotEmpty(schemeCarList)){
                resourceDispatchDto.setSchemeCarCount(schemeCarList.size());
                for(DrainCommandDispatchSchemeCar schemeCar:schemeCarList){
                    LambdaQueryWrapper<InstructCar> queryWrapper = Wrappers.lambdaQuery();
                    queryWrapper.eq(InstructCar::getCarId, schemeCar.getMnCarId());
                    queryWrapper.eq(InstructCar::getStatus, "ACCEPT");
                    queryWrapper.eq(InstructCar::getCmUsable, false);
                    List<InstructCar> instructCarList = instructCarMapper.selectList(queryWrapper);
                    if(CollectionUtils.isNotEmpty(instructCarList)){
                        schemeCar.setAssignedFlag(true);
                    }else{
                        schemeCar.setAssignedFlag(false);
                    }
                }
                //筛选待命的车辆
                selectSchemeCarList = schemeCarList.stream().filter(schemeCar -> !schemeCar.getAssignedFlag()).collect(Collectors.toList());

            }
            DrainCommandDispatchSchemeTeam drainCommandDispatchSchemeTeam = new DrainCommandDispatchSchemeTeam();
            drainCommandDispatchSchemeTeam.setLevel(dangerSituation.getReservePlanLevel());
            drainCommandDispatchSchemeTeam.setSchemeId(query.getSchemeId());
            List<DrainCommandDispatchSchemeTeam> schemeTeamList =drainCommandDispatchSchemeTeamMapper.getPageList(drainCommandDispatchSchemeTeam);
            if(CollectionUtils.isNotEmpty(schemeTeamList)) {
                resourceDispatchDto.setSchemeTeamCount(schemeTeamList.size());
                for(DrainCommandDispatchSchemeTeam schemeTeam:schemeTeamList){
                    LambdaQueryWrapper<InstructTeam> queryWrapper = Wrappers.lambdaQuery();
                    queryWrapper.eq(InstructTeam::getTeamId, schemeTeam.getMnTeamId());
                    queryWrapper.eq(InstructTeam::getStatus, "ACCEPT");
                    queryWrapper.eq(InstructTeam::getCmUsable, false);
                    List<InstructTeam> instructTeamList = instructTeamMapper.selectList(queryWrapper);
                    if(CollectionUtils.isNotEmpty(instructTeamList)){
                        schemeTeam.setAssignedFlag(true);
                    }else{
                        schemeTeam.setAssignedFlag(false);
                    }
                }
                //筛选待命的车辆
                selectSchemeTeamList = schemeTeamList.stream().filter(schemeTeam -> !schemeTeam.getAssignedFlag()).collect(Collectors.toList());
            }
        }
        resourceDispatchDto.setSchemeCarList(selectSchemeCarList);
        resourceDispatchDto.setSchemeTeamList(selectSchemeTeamList);
        return resourceDispatchDto;
    }

    @Override
    public ResourceDispatchDto fetchList(ResourceDispatchQuery query) {
            ResourceDispatchDto resourceDispatchDto = new ResourceDispatchDto();
        resourceDispatchDto.setDangerSituationId(query.getDangerSituationId());
        //当前为资源实际需要的，过滤则为待命的
        List<DrainBaseMnWarehouseDto> drainBaseMnWarehouseDtoList  = iResourceWarehouseService.list(query.getDangerSituationId());
        List<DrainBaseMnWarehouseDto> sortdrainBaseMnWarehouseDtoList = drainBaseMnWarehouseDtoList.stream().sorted(Comparator.comparing(DrainBaseMnWarehouseDto::getDistance)).collect(Collectors.toList());
        resourceDispatchDto.setDrainBaseMnWarehouseDtoList(sortdrainBaseMnWarehouseDtoList);

        List<ResourceCarDto> resourceCarDtoList = iResourceCarService.list(query.getDangerSituationId());
        List<ResourceCarDto> sortResourceCarDtoList = resourceCarDtoList.stream().sorted(Comparator.comparing(ResourceCarDto::getDistance)).collect(Collectors.toList());
        resourceDispatchDto.setResourceCarDtoList(sortResourceCarDtoList);

        List<ResourceTeamDto> resourceTeamDtoList = iResourceTeamService.list(query.getDangerSituationId());
        List<ResourceTeamDto> sortResourceTeamDtoList = resourceTeamDtoList.stream().sorted(Comparator.comparing(ResourceTeamDto::getDistance)).collect(Collectors.toList());
        resourceDispatchDto.setResourceTeamDtoList(sortResourceTeamDtoList);


        //当前待命队伍 7  组：根据险情位置、响应等级、人员数量、用时、距离等方面综合分析，建议选择：抢险1队、抢险2队；
        //当前待命车辆 5 辆：根据车型、排量、车辆状态、响应等级、用时、路况、距离等方面综合分析，建议选择：皖F34332、皖F34332、皖
        String carName;
        String teamName;
        long carCount = sortResourceCarDtoList.stream().filter(resourceCarDto -> !resourceCarDto.getAssignedFlag()).count();
        List<ResourceCarDto> selectCarList = sortResourceCarDtoList.stream().filter(resourceCarDto -> !resourceCarDto.getAssignedFlag()).collect(Collectors.toList());
       if(selectCarList.size()>0) {
           if (selectCarList.size() >= 2) {
               carName = selectCarList.get(0).getCarName() + "、" + selectCarList.get(1).getCarName();
           } else {
               carName = selectCarList.get(0).getCarName();
           }
       }else{
           carName = "";
       }
        //
        long teamCount = sortResourceTeamDtoList.stream().filter(resourceTeamDto -> !resourceTeamDto.getAssignedFlag()).count();
        List<ResourceTeamDto> selectTeamList = sortResourceTeamDtoList.stream().filter(resourceTeamDto -> !resourceTeamDto.getAssignedFlag()).collect(Collectors.toList());
        if(selectTeamList.size()>0) {
            if (selectTeamList.size() >= 2) {
                teamName = selectTeamList.get(0).getTeamName() + "、" + selectTeamList.get(1).getTeamName();
            } else {
                teamName = selectTeamList.get(0).getTeamName();
            }
        }else{
            teamName = "";
        }
        resourceDispatchDto.setResourceDispatchSuggest(String.format("当前待命队伍 %s 组：根据险情位置、响应等级、人员数量、用时、距离等方面综合分析，建议选择：%s；" +
                        "当前待命车辆 %s 辆：根据车型、排量、车辆状态、响应等级、用时、路况、距离等方面综合分析，建议选择：%s", teamCount, StringUtils.isNotBlank(teamName) ? teamName : "",
                carCount, StringUtils.isNotBlank(carName) ? carName : ""));
        //默认查询的就是待命的
        resourceDispatchDto.setResourceCarDtoList(selectCarList);
        resourceDispatchDto.setResourceTeamDtoList(selectTeamList);

        return resourceDispatchDto;
    }

    @Transactional(rollbackFor = Throwable.class)
    @Override
    public Long save(ResourceDispatchDto dto, Boolean flag) {
        //应急车辆批量保存
        iInstructCarService.saveBatch(dto);
        //应急队伍批量保存
        iInstructTeamService.saveBatch(dto);
        //应急仓库批量保存
        instructWarehouseService.saveBatch(dto);
        //确定资源调度时间
        if (flag) {
            DangerSituationManage dangerSituationManage = dangerSituationManageMapper.selectById(dto.getDangerSituationId());
            dangerSituationManage.setResourceDispatchTime(LocalDateTime.now());
            dangerSituationManage.setResourceDispatchSuggest(dto.getResourceDispatchSuggest());
            dangerSituationManage.setDispatchContent(dto.getDispatchContent());
            dangerSituationManageMapper.updateById(dangerSituationManage);
        }
        return dto.getDangerSituationId();
    }



    @Override
    public Boolean sendMessage(SendMessageRequest request) {
        if (StringUtils.isEmpty(request.getContent())) {
            throw new BusinessException("短信内容不能为空");
        }
        if (StringUtils.isEmpty(request.getMobile())) {
            throw new BusinessException("手机联系人不能为空");
        }
        HashMap<String, String> headers = new HashMap<>();
        headers.put("app_secret",
                appSecret);

        try {
            String[] mobile = request.getMobile().split(",");
            ArrayList<String> mobiles = new ArrayList<>();
            for (String phone : mobile) {
                if (!isMobile(phone)){
                    throw new BusinessException(phone+"手机格式不正确");
                }
                mobiles.add(phone);
            }
            SendMessage sendMessage = new SendMessage();
            sendMessage.setContent(request.getContent());
            sendMessage.setMobile(mobiles);

            String response = HttpUtils.post(host, JSON.toJSONString(sendMessage), headers);
            logger.info("小辰云调度短信发送接口{}", "请求参数:" + JSON.toJSONString(sendMessage) + "    返回结果:" + response.toString());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    public static boolean isMobile(String mobile) {
        String regex = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(16[5,6])|(17[0-8])|(18[0-9])|(19[1、5、8、9]))\\d{8}$";
        Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
        Matcher m = p.matcher(mobile);
        return m.matches();
    }
}
